package com.iteaj.iot.client.protocol;

import com.iteaj.iot.ProtocolType;
import com.iteaj.iot.client.IotClientBootstrap;
import com.iteaj.iot.client.SocketClient;
import com.iteaj.iot.client.component.SingleTcpClientComponent;
import com.iteaj.iot.client.*;
import com.iteaj.iot.client.component.SocketClientComponent;
import com.iteaj.iot.config.ConnectProperties;
import com.iteaj.iot.protocol.socket.AbstractSocketProtocol;
import io.netty.channel.socket.DatagramPacket;

/**
 * create time: 2021/8/6
 *
 * @author iteaj
 * @since 1.0
 */
public abstract class ClientSocketProtocol<C extends ClientMessage> extends AbstractSocketProtocol<C> implements ClientProtocol<C> {

    /**
     * 用来获取客户端
     * @see SocketClient
     * @see #getIotClient()
     */
    private ConnectProperties clientKey;
    /**
     * udp协议报文
     */
    private DatagramPacket packet;

    private ClientProtocolHandle defaultProtocolHandle; // 默认协议处理器

    @Override
    public C requestMessage() {
        return super.requestMessage();
    }

    @Override
    public C responseMessage() {
        return super.responseMessage();
    }

    @Override
    public abstract ProtocolType protocolType();

    /**
     * 返回客户端
     * @return
     */
    public SocketClient getIotClient() {
        ClientComponent clientComponent = IotClientBootstrap.getClientComponentFactory().getByClass(requestMessage.getClass());
        if(clientComponent instanceof SingleTcpClientComponent && getClientKey() != null) {
            throw new IllegalStateException("组件["+clientComponent.getName()+"]属于单客户端组件, 不支持使用方法 #request(host, port)");
        }

        if(this.getClientKey() != null) {
            SocketClient client = (SocketClient) clientComponent.getClient(getClientKey());

            if(client != null) {
                return client;
            }

            synchronized (clientComponent) {
                client = (SocketClient) clientComponent.getClient(getClientKey());
                if(client != null) {
                    return client;
                }

                client = (SocketClient) clientComponent.createNewClient(this.getClientKey());
                client.init(IotClientBootstrap.clientGroup);
                client.connect(null, 5000);
                return client;
            }
        } else {
            return (SocketClient) clientComponent.getClient(clientComponent.getConfig());
        }
    }

    protected String getMessageId() {
        ClientMessage message = requestMessage();
        return message.getMessageId();
    }

    public ClientProtocolHandle getDefaultProtocolHandle() {
        if(defaultProtocolHandle == null) {
            defaultProtocolHandle = (ClientProtocolHandle) IotClientBootstrap
                    .businessFactory.getProtocolHandle(getClass());
        }

        return defaultProtocolHandle;
    }

    public DatagramPacket getPacket() {
        return packet;
    }

    public void setPacket(DatagramPacket packet) {
        this.packet = packet;
    }

    public ConnectProperties getClientKey() {
        return clientKey;
    }

    public ClientSocketProtocol setClientKey(ConnectProperties clientKey) {
        this.clientKey = clientKey;
        return this;
    }
}
